﻿//
// Copyright 2024 Exhunter Technology Co.Ltd2.
//

using System.Collections.Generic;

namespace X18.Framework.Core.Security
{
    /// <summary>
    /// 数据加密算法类型
    /// </summary>
    public enum DataEncryptorType
    {
        /// <summary>
        /// 一般加密类型
        /// </summary>
        Normal,
        /// <summary>
        /// SM2加密类型
        /// </summary>
        SM2,
        /// <summary>
        /// SM4加密类型
        /// </summary>
        SM4,
        /// <summary>
        /// RSA加密类型
        /// </summary>
        RSA,
        /// <summary>
        /// AES加密类型
        /// </summary>
        AES
    }

    /// <summary>
    /// 数据加密算法类
    /// </summary>
    public static class DataEncryptor
    {
        /// <summary>
        /// 数据加密算法实例
        /// </summary>
        private static Dictionary<DataEncryptorType, IDataEncryptor> encryptors;

        static DataEncryptor()
        {
            encryptors = new Dictionary<DataEncryptorType, IDataEncryptor>
            {
                { DataEncryptorType.Normal, new Encryptor.ProclaimTextEncryptor() },
                { DataEncryptorType.SM2, new Encryptor.Sm2Encryptor() },
                { DataEncryptorType.SM4, new Encryptor.Sm4Encryptor() },
                { DataEncryptorType.RSA, new Encryptor.RsaEncryptor() },
                { DataEncryptorType.AES, new Encryptor.AesEncryptor() }
            };
        }

        /// <summary>
        /// 获取加密器
        /// </summary>
        /// <param name="encryptedType">加密类型</param>
        /// <returns>加密器</returns>
        public static IDataEncryptor GetEncryptor(DataEncryptorType encryptedType = DataEncryptorType.SM4)
        {
            if (!encryptors.ContainsKey(encryptedType))
            {
                encryptedType = DataEncryptorType.SM4;
            }
            return encryptors[encryptedType];
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="encryptedType">加密类型</param>
        /// <returns></returns>
        public static string EncryptToString(string plainText, byte[] key = null, DataEncryptorType encryptedType = DataEncryptorType.SM2)
        {
            IDataEncryptor encryptor = GetEncryptor(encryptedType);
            string cipherText = encryptor.EncryptToString(plainText, key);
            return cipherText;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="plainText">密文</param>
        /// <param name="encryptedType">加密类型</param>
        /// <returns></returns>
        public static string DecryptFromString(string cipherText, byte[] key = null, DataEncryptorType encryptedType = DataEncryptorType.SM2)
        {
            IDataEncryptor encryptor = GetEncryptor(encryptedType);
            string plainText = encryptor.DecryptFromString(cipherText, key);
            return plainText;
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="encryptedType">加密类型</param>
        /// <returns></returns>
        public static byte[] EncryptToBytes(byte[] plainBytes, byte[] key = null, DataEncryptorType encryptedType = DataEncryptorType.SM2)
        {
            IDataEncryptor encryptor = GetEncryptor(encryptedType);
            byte[] cipherText = encryptor.EncryptToBytes(plainBytes, key);
            return cipherText;
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="plainText">密文</param>
        /// <param name="encryptedType">加密类型</param>
        /// <returns></returns>
        public static byte[] DecryptFromBytes(byte[] cipherText, byte[] key = null, DataEncryptorType encryptedType = DataEncryptorType.SM2)
        {
            IDataEncryptor encryptor = GetEncryptor(encryptedType);
            byte[] plainBytes = encryptor.DecryptFromBytes(cipherText, key);
            return plainBytes;
        }

        /// <summary>
        /// 生成密码字符串
        /// </summary>
        public static string GenerateKey(DataEncryptorType encryptedType)
        {
            IDataEncryptor encryptor = GetEncryptor(encryptedType);
            string key = encryptor.GenerateKey();
            return key;
        }
    }
}